home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998…eptember: Technology Seed / September 98 ADC Seed CD.toast / Language Analysis Manager / DarumaDR1Package / Examples / LanguageAnalysisTestApp / Sources / Analysis.c next >
Encoding:
C/C++ Source or Header  |  1998-03-27  |  32.9 KB  |  1,064 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        Analysis.c
  3.  
  4.      Contains:    Sample code for Language Analysis Manager.
  5.  
  6.      Version:    Technology:    System 8
  7.                  Release:    Daruma Developer Release 1
  8.  
  9.      Copyright:    1998 by Apple Computer, Inc., all rights reserved
  10.  
  11.      Contact:    daruma@apple.com
  12.  
  13. */
  14.  
  15.  
  16. #include "TestApp.h"
  17. #include "FunctionProto.h"
  18.  
  19. #include <TextUtils.h>
  20. #include <Memory.h>
  21. #include <AppleEvents.h>
  22. #include <Menus.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <Script.h>
  26.  
  27. #include <LanguageAnalysis.h>
  28. #include <JapaneseAnalysisEngine.h>
  29.  
  30.  
  31. // ========================================================================================
  32. // Prototypes for static functions
  33. // ========================================================================================
  34. static OSStatus CallLanguageAnalysis ( LAContextRef analysisContext, short analysisMode, short wholeStrLen, short inputStrLen, const char *inputStr,  AEDesc *result, Boolean *modified );
  35. static void PrintPath( LAMorphemePath *thePath, short analysisClass );
  36. static void PrintStreamFromPath( LAMorphemePath *thePath );
  37. static void PrintStreamFromBundle( LAMorphemeBundle *theBundle, short number );
  38. static OSStatus GetStandalonePathFromBundle( LAMorphemeBundle *bundle, UInt16 index, LAMorphemePath *morphemePath );
  39.  
  40.  
  41. // ========================================================================================
  42. // SetUpAllAnalysisEnvironment
  43. // ========================================================================================
  44. OSStatus SetUpAllAnalysisEnvironment ( InputDialogPtr infoDialogPtr )
  45. {
  46.     OSStatus            err;
  47.     UInt32                actualNumber, i;
  48.     ControlRef            control;
  49.     LAEnvironmentRef    *environmentList;
  50.     Str63                environmentName;
  51.     MenuHandle            envMenuHandle = GetMenuHandle( kEnvironmentMenuID);
  52.     
  53.     // Get number of available environments
  54.     err = LAGetEnvironmentList( 0, &actualNumber, NULL);
  55.     nrequire( err, getEnvNum_Failure);
  56.     
  57.     // Allocate buffer for environment list
  58.     environmentList = (LAEnvironmentRef *)NewPtrClear( sizeof(LAEnvironmentRef) * actualNumber);
  59.     require_action( environmentList, allocEnvRef_Failure, err = memFullErr;);
  60.     
  61.     // Get environment list
  62.     err = LAGetEnvironmentList( actualNumber, &actualNumber, environmentList);
  63.     nrequire( err, getEnvRef_Failure);
  64.     
  65.     for ( i = 0; i < actualNumber; i++)
  66.     {
  67.         err = LAGetEnvironmentName( environmentList[i], environmentName);
  68.         nrequire( err, getEnvName_Failure);
  69.         
  70.         AppendMenu( envMenuHandle, "\pDummy");
  71.         SetMenuItemText( envMenuHandle, i + 1, environmentName);
  72.     }
  73.     
  74.     control = (ControlRef)GetDialogItemHandle( infoDialogPtr->dialog, kEnvironPopupDItemID);
  75.     SetControlMaximum( control, actualNumber);
  76.     
  77.     DisposePtr( (Ptr)environmentList);
  78.     
  79.     return noErr;
  80.     
  81.     //`````````````````````````````````````````````````````````````````````````````
  82.     // Error handling
  83.     //
  84. getEnvName_Failure:
  85. getEnvRef_Failure:
  86.     DisposePtr( (Ptr)environmentList);
  87. allocEnvRef_Failure:
  88. getEnvNum_Failure:
  89.     return err;
  90. }
  91.  
  92.  
  93. // ========================================================================================
  94. // SetAnalysisEnvironment
  95. // ========================================================================================
  96. OSStatus SetAnalysisEnvironment ( InputDialogPtr infoDialogPtr )
  97. {
  98.     OSStatus            err, specificErr;
  99.     ControlRef            control;
  100.     short                newEnvNum, level;
  101.     Str63                envName;
  102.     
  103.     //------------------------------------------------------------------------------
  104.     // Get dialog popup menu
  105.     //
  106.     control = (ControlRef)GetDialogItemHandle( infoDialogPtr->dialog, kEnvironPopupDItemID);
  107.     newEnvNum = GetControlValue( control);
  108.     GetMenuItemText( GetMenuHandle( kEnvironmentMenuID), newEnvNum, envName);
  109.     
  110.     //------------------------------------------------------------------------------
  111.     // Close current analysis context
  112.     //
  113.     if ( infoDialogPtr->analysisContext != NULL)
  114.     {
  115.         err = LACloseContext( infoDialogPtr->analysisContext);
  116.         nrequire( err, closeContext_Failure);
  117.     }
  118.     
  119.     //------------------------------------------------------------------------------
  120.     // Get new environment
  121.     //
  122.     err = LAGetEnvironmentRef( envName, &infoDialogPtr->environmentRef);
  123.     nrequire( err, getEnvironment_Failure);
  124.  
  125.     //------------------------------------------------------------------------------
  126.     // Open new analysis context
  127.     //
  128.     err = LAOpenContext( infoDialogPtr->environmentRef, &infoDialogPtr->analysisContext, &specificErr, NULL );
  129.     nrequire( err, openContext_Failure);
  130.  
  131.     //------------------------------------------------------------------------------
  132.     // Set level menu
  133.     //
  134.     UncheckAllMenuItems( kLevelMenuID);
  135.     
  136.     err = GetAnalysisLevel( infoDialogPtr, &level);
  137.     nrequire( err, getProperty_Failure);
  138.     
  139.     if ( level == 0)
  140.         CheckItem( GetMenuHandle( kLevelMenuID), kLevelZeroMenuItemID, true);
  141.     else
  142.         CheckItem( GetMenuHandle( kLevelMenuID), level + kLevelOneMenuItemID - 1, true);
  143.  
  144.     infoDialogPtr->curAnalysisClass = newEnvNum;
  145.     infoDialogPtr->converted = false;
  146.     
  147.     return noErr;
  148.     
  149.     //`````````````````````````````````````````````````````````````````````````````
  150.     // Error handling
  151.     //
  152. getProperty_Failure:
  153. openContext_Failure:
  154. getEnvironment_Failure:
  155. closeContext_Failure:
  156.     return err;
  157. }
  158.  
  159.  
  160. // ========================================================================================
  161. // DoMorphemeAnalysis
  162. // ========================================================================================
  163. OSStatus DoMorphemeAnalysis ( InputDialogPtr infoDialogPtr )
  164. {
  165.     OSStatus            err;
  166.     Handle                itemHandle;
  167.     short                inputStrLen, partialStrLen;
  168.     Str255                inputStr, partialStr;
  169.     LAContextRef        analysisContext;
  170.  
  171.     //------------------------------------------------------------------------------
  172.     // Initialize
  173.     //
  174.     if ( infoDialogPtr->analysisBundle.descriptorType != typeNull)
  175.         AEDisposeDesc( &infoDialogPtr->analysisBundle);
  176.  
  177.     if ( infoDialogPtr->analysisPath.descriptorType != typeNull)
  178.         AEDisposeDesc( &infoDialogPtr->analysisPath);
  179.  
  180.     //------------------------------------------------------------------------------
  181.     // Get item string
  182.     //
  183.     itemHandle = GetDialogItemHandle( infoDialogPtr->dialog, kInputEditTextDItemID);
  184.     GetDialogItemText( itemHandle, inputStr);
  185.     inputStrLen = inputStr[0];
  186.     PascalStrToCStr( inputStr);
  187.     
  188.     analysisContext = infoDialogPtr->analysisContext;
  189.     
  190.     //------------------------------------------------------------------------------
  191.     // Call analysis function
  192.     //
  193.     if ( gAnalysisMode == kBatchAnalysisMode )
  194.     {
  195.         err = CallLanguageAnalysis( analysisContext, gAnalysisMode, inputStrLen, inputStrLen,
  196.                                    (char *)inputStr, &infoDialogPtr->analysisBundle, NULL);
  197.         nrequire( err, batchAnalysis_Failure);
  198.         
  199.         PrintStreamFromBundle( &infoDialogPtr->analysisBundle, 1);
  200.     }
  201.     else
  202.     {
  203.         Boolean        modified;
  204.         Handle        strItemHandle;
  205.         short        charKind;
  206.         
  207.         partialStr[0] = '\0';
  208.         strItemHandle = GetDialogItemHandle( infoDialogPtr->dialog, kInputStatTextDItemID);
  209.         SetDialogItemText( strItemHandle, "\p");
  210.         
  211.         //
  212.         // Handle 1-byte and 2-byte characters
  213.         //
  214.         for ( partialStrLen = 0; partialStrLen < inputStrLen; )
  215.         {
  216.             //
  217.             // The target script (or locale) should be specified by environment.
  218.             // For present, using Japanese script as a target script.
  219.             //
  220.             charKind = CharacterByteType( (char *)inputStr, partialStrLen, smJapanese);
  221.             
  222.             if ( charKind == smSingleByte)
  223.                 partialStrLen++;
  224.             else if ( charKind == smFirstByte)
  225.                 partialStrLen += 2;
  226.             
  227.             BlockMoveData( inputStr, partialStr, partialStrLen);
  228.             partialStr[partialStrLen] = '\0';
  229.             
  230.             CStrToPascalStr( (char *)partialStr);
  231.             SetDialogItemText( strItemHandle, partialStr);
  232.             PascalStrToCStr( partialStr);
  233.             
  234.             err = CallLanguageAnalysis( analysisContext, gAnalysisMode, inputStrLen,
  235.                                         partialStrLen, (char *)partialStr,
  236.                                         &infoDialogPtr->analysisPath, &modified);
  237.             nrequire( err, continuousAnalysis_Failure);
  238.             
  239.             if ( modified)
  240.             {
  241.                 PrintStreamFromPath( &infoDialogPtr->analysisPath);
  242.                 AEDisposeDesc( &infoDialogPtr->analysisPath);
  243.             }
  244.             
  245.             partialStr[0] = '\0';
  246.         }
  247.         
  248.         err = LAResetAnalysis( analysisContext);
  249.     }
  250.     
  251.     return noErr;
  252.     
  253.     //`````````````````````````````````````````````````````````````````````````````
  254.     // Error handling
  255.     //
  256. continuousAnalysis_Failure:
  257.     if ( infoDialogPtr->analysisPath.descriptorType != typeNull)
  258.         AEDisposeDesc( &infoDialogPtr->analysisPath);
  259. batchAnalysis_Failure:
  260. closeContext_Failure:
  261. openContext_Failure:
  262. context_Failure:
  263.     return err;
  264. }
  265.  
  266.  
  267. // ========================================================================================
  268. // CallLanguageAnalysis
  269. // ========================================================================================
  270. static OSStatus CallLanguageAnalysis ( LAContextRef analysisContext, short analysisMode,
  271.                                        short wholeStrLen, short inputStrLen, const char *inputStr,
  272.                                        AEDesc *result, Boolean *modified )
  273. {
  274.     OSStatus            err;
  275.     LAMorphemePath        *leadingEdge, *trailingEdge;
  276.     Boolean                modifyStatus;
  277.     
  278.     //------------------------------------------------------------------------------
  279.     // Do analysis
  280.     //
  281.     if ( analysisMode == kBatchAnalysisMode)
  282.     {
  283.         //
  284.         // Batch analysis
  285.         //
  286.         leadingEdge  = (LAMorphemePath *)kLADefaultEdge;
  287.         trailingEdge = (LAMorphemePath *)kLADefaultEdge;
  288.  
  289.         err = LAMorphemeAnalysis( analysisContext, inputStr, inputStrLen, leadingEdge,
  290.                                   trailingEdge, kNumResult, result);
  291.         nrequire( err, batchAnalysis_Failure);
  292.     }
  293.     else
  294.     {
  295.         //
  296.         // Continuous analusis
  297.         //
  298.         leadingEdge  = (LAMorphemePath *)kLADefaultEdge;
  299.         if ( inputStrLen == wholeStrLen)
  300.             trailingEdge = (LAMorphemePath *)kLADefaultEdge;
  301.         else
  302.             trailingEdge = (LAMorphemePath *)kLAIncompleteEdge;
  303.  
  304.         err = LAContinuousMorphemeAnalysis( analysisContext, inputStr, inputStrLen, false,
  305.                                             leadingEdge, trailingEdge, &modifyStatus);
  306.         nrequire( err, continuousAnalysis_Failure);
  307.         
  308.         //
  309.         // Update display every time when internal analysis state is changed
  310.         //
  311.         if ( modifyStatus)
  312.         {
  313.             err = LAGetMorphemes( analysisContext, result);
  314.             nrequire( err, getMorpheme_Failure);
  315.         }
  316.  
  317.         if ( modified != NULL)
  318.             *modified = modifyStatus;
  319.     }
  320.     
  321.     return noErr;
  322.  
  323.     //`````````````````````````````````````````````````````````````````````````````
  324.     // Error handling
  325.     //
  326. getMorpheme_Failure:
  327. continuousAnalysis_Failure:
  328. batchAnalysis_Failure:
  329.     return err;
  330. }
  331.  
  332.  
  333. // ========================================================================================
  334. // ReleaseAnalysisEnvironment
  335. // ========================================================================================
  336. OSStatus ReleaseAnalysisContext ( InputDialogPtr infoDialogPtr )
  337. {
  338.     OSStatus        err;
  339.     
  340.     //------------------------------------------------------------------------------
  341.     // Close current analysis context
  342.     //
  343.     if ( infoDialogPtr->analysisContext != NULL)
  344.     {
  345.         err = LACloseContext( infoDialogPtr->analysisContext);
  346.         nrequire( err, closeContext_Failure);
  347.     }
  348.  
  349.     return noErr;
  350.     
  351.     //`````````````````````````````````````````````````````````````````````````````
  352.     // Error handling
  353.     //
  354. closeContext_Failure:
  355.     return err;
  356. }
  357.  
  358.  
  359. // ========================================================================================
  360. // GetAnalysisLevel
  361. // ========================================================================================
  362. OSStatus GetAnalysisLevel ( InputDialogPtr infoDialogPtr, short *level )
  363. {
  364.     OSStatus            err;
  365.     long                actualSize;
  366.     DescType            typeCode;
  367.     AERecord            propertyContainer = { typeNull, NULL};
  368.     
  369.     err = LAGetEnvironmentProperty( infoDialogPtr->environmentRef, keyAELAAnalysisLevel,
  370.                                     &propertyContainer);
  371.     nrequire( err, getProperty_Failure);
  372.     
  373.     err = AEGetKeyPtr( &propertyContainer, keyAELAAnalysisLevel, typeAELAEnvAnalysisLevel,
  374.                        &typeCode, level, sizeof(short), &actualSize);
  375.     nrequire( err, getLevel_Failure);
  376.     
  377.     AEDisposeDesc( &propertyContainer);
  378.     
  379.     return noErr;
  380.     
  381.     //`````````````````````````````````````````````````````````````````````````````
  382.     // Error handling
  383.     //
  384. getLevel_Failure:
  385.     AEDisposeDesc( &propertyContainer);
  386. getProperty_Failure:
  387.     return err;
  388. }
  389.  
  390.  
  391. // ========================================================================================
  392. // SetAnalysisLevel
  393. // ========================================================================================
  394. OSStatus SetAnalysisLevel ( InputDialogPtr infoDialogPtr, short level )
  395. {
  396.     OSStatus            err, specificErr;
  397.     AERecord            propertyContainer = { typeNull, NULL};
  398.     
  399.     err = AECreateList( NULL, 0L, true, &propertyContainer);
  400.     nrequire( err, createContainer_Failure);
  401.  
  402.     err = AEPutKeyPtr( &propertyContainer, keyAELAAnalysisLevel, typeAELAEnvAnalysisLevel,
  403.                        &level, sizeof( level));
  404.     nrequire( err, addLevel_Failure);
  405.  
  406.     err = LASetEnvironmentProperty( infoDialogPtr->environmentRef, keyAELAAnalysisLevel,
  407.                                     &propertyContainer, &specificErr);
  408.     nrequire( err, setProperty_Failure);
  409.     
  410.     AEDisposeDesc( &propertyContainer);
  411.     
  412.     return noErr;
  413.     
  414.     //`````````````````````````````````````````````````````````````````````````````
  415.     // Error handling
  416.     //
  417. setProperty_Failure:
  418. addLevel_Failure:
  419.     AEDisposeDesc( &propertyContainer);
  420. createContainer_Failure:
  421.     return err;
  422. }
  423.  
  424.  
  425.  /*    ========================================================================================
  426.     Routine:    PrintBundle
  427.     
  428.     Purpose:    Print a bundle using GetStandalonePathFromBundle().
  429.     
  430.     Warnings:
  431.     ======================================================================================== */
  432. void
  433. PrintBundle(
  434.     LAMorphemeBundle    *theBundle,
  435.     short                analysisClass,
  436.     short                number
  437. )
  438. {
  439.     OSStatus            err;
  440.     long                i, begin, end;
  441.     AEDescList            morphemePathList    = { typeNull, NULL};
  442.     AERecord            morphemePath        = { typeNull, NULL};
  443.     long                pathCount;
  444.  
  445.     //------------------------------------------------------------------------------
  446.     // Count path in the morpheme path list
  447.     //
  448.     err = AEGetKeyDesc( theBundle, keyAELAMorphemePath, typeAEList, &morphemePathList);
  449.     if ( err != noErr) goto errExit;
  450.  
  451.     err = AECountItems( &morphemePathList, &pathCount);
  452.     if ( pathCount == 0)
  453.     {
  454.         PutCStringConsoleWindow( gConsoleWindow, "There is no path.\n");
  455.         goto errExit;
  456.     }
  457.     
  458.     if ( number == 0)
  459.     {
  460.         begin = 1;
  461.         end = pathCount;
  462.     }
  463.     else if ( number > pathCount)
  464.     {
  465.         PutCStringConsoleWindow( gConsoleWindow, "There is no more text\n");
  466.         goto errExit;
  467.     }
  468.     else
  469.     {
  470.         begin = end = number;
  471.     }
  472.     
  473.     PutCStringConsoleWindow( gConsoleWindow, "\n");
  474.  
  475.     for ( i = begin; i <= end; i++)
  476.     {
  477.         err = GetStandalonePathFromBundle( theBundle, i, &morphemePath);
  478.         if ( err != noErr) goto errExit;
  479.         
  480.         PrintPath( &morphemePath, analysisClass);
  481.         AEDisposeDesc( &morphemePath);
  482.         
  483.         PutCStringConsoleWindow( gConsoleWindow, "\n");
  484.     }
  485.     
  486.     AEDisposeDesc( &morphemePathList);
  487.     
  488.     return;
  489.  
  490. errExit:
  491.     AEDisposeDesc( &morphemePath);
  492.     AEDisposeDesc( &morphemePathList);
  493. }
  494.  
  495.  
  496.  /*    ========================================================================================
  497.     Routine:    PrintStreamFromBundle
  498.     
  499.     Purpose:    Print a particular result specified by number in the bundle.
  500.     
  501.     Warnings:
  502.     ======================================================================================== */
  503. void
  504. PrintStreamFromBundle(
  505.     LAMorphemeBundle    *theBundle,
  506.     short                number
  507. )
  508. {
  509.     OSStatus        err;
  510.     long            i, j, begin, end, numItems, morphemeIndex;
  511.     long            morphemeNum;
  512.     AEDescList        morphemeNodeList    = { typeNull, NULL};
  513.     AEDescList        morphemePathList    = { typeNull, NULL};
  514.     AEDescList        morphemeIndexList    = { typeNull, NULL};
  515.     AERecord        morphemePath        = { typeNull, NULL};
  516.     AERecord        morpheme            = { typeNull, NULL};
  517.     AEDescList        homographList        = { typeNull, NULL};
  518.     AERecord        homograph            = { typeNull, NULL};
  519.     AEKeyword        theAEKeyword;
  520.     DescType        typeCode;
  521.     long            actualSize;
  522.     char            dataStr[kSizeOfAnalysis];
  523.     char            resultStr[kSizeOfAnalysis];
  524.     
  525.     //------------------------------------------------------------------------------
  526.     // Get morpheme node list
  527.     //
  528.     err = AEGetKeyDesc( theBundle, keyAELAMorpheme, typeAEList, &morphemeNodeList);
  529.     if ( err != noErr) goto errExit;
  530.     
  531.     //------------------------------------------------------------------------------
  532.     // Get morpheme path list
  533.     //
  534.     err = AEGetKeyDesc( theBundle, keyAELAMorphemePath, typeAEList, &morphemePathList);
  535.     if ( err != noErr) goto errExit;
  536.     
  537.     AECountItems( &morphemePathList, &numItems);
  538.     
  539.     if ( number == 0)
  540.     {
  541.         begin = 1;
  542.         end = numItems;
  543.     }
  544.     else if ( number > numItems)
  545.     {
  546.         PutCStringConsoleWindow( gConsoleWindow, "There is no more text\n");
  547.         goto errExit;
  548.     }
  549.     else
  550.     {
  551.         begin = end = number;
  552.     }
  553.     
  554.     for ( i = begin; i <= end; i++)
  555.     {
  556.         resultStr[0] = 0;
  557.         
  558.         //------------------------------------------------------------------------------
  559.         // Get morpheme path from morpheme path list one by one
  560.         //
  561.         err = AEGetNthDesc( &morphemePathList, i, typeAERecord, &theAEKeyword, &morphemePath);
  562.         if ( err != noErr) goto errExit;
  563.         
  564.         //------------------------------------------------------------------------------
  565.         // Get morpheme index list from morpheme path
  566.         //
  567.         err = AEGetKeyDesc( &morphemePath, keyAELAMorpheme, typeAEList, &morphemeIndexList);
  568.         AEDisposeDesc( &morphemePath);
  569.         if ( err != noErr) goto errExit;
  570.         
  571.         err = AECountItems( &morphemeIndexList, &morphemeNum);
  572.         
  573.         for ( j = 1; j <= morphemeNum; j++)
  574.         {
  575.             //------------------------------------------------------------------------------
  576.             // Get morpheme index from morpheme index list one by one
  577.             //
  578.             err = AEGetNthPtr( &morphemeIndexList, j, typeInteger, &theAEKeyword, &typeCode,
  579.                                &morphemeIndex, sizeof(morphemeIndex), &actualSize);
  580.             if ( err != noErr) goto errExit;
  581.             
  582.             //------------------------------------------------------------------------------
  583.             // Get morpheme node, specified by index, from morpheme node list
  584.             //
  585.             err = AEGetNthDesc( &morphemeNodeList, morphemeIndex, typeAERecord, &theAEKeyword,
  586.                                 &morpheme);
  587.             if ( err != noErr) goto errExit;
  588.             
  589.             //------------------------------------------------------------------------------
  590.             // Get homograph list from morpheme node
  591.             //
  592.             err = AEGetKeyDesc( &morpheme, keyAELAHomograph, typeAEList, &homographList);
  593.             AEDisposeDesc( &morpheme);
  594.             if ( err != noErr) goto errExit;
  595.             
  596.             //------------------------------------------------------------------------------
  597.             // Get homograph node from homograph list
  598.             //
  599.             err = AEGetNthDesc( &homographList, 1, typeAERecord, &theAEKeyword, &homograph);
  600.             AEDisposeDesc( &homographList);
  601.             if ( err != noErr) goto errExit;
  602.             
  603.             //------------------------------------------------------------------------------
  604.             // Get data string (hyoki or yomi) from homograph node
  605.             //
  606.             err = AEGetKeyPtr( &homograph, keyAEText, typeChar, &typeCode, dataStr,
  607.                                kSizeOfAnalysis, &actualSize);
  608.             AEDisposeDesc( &homograph);
  609.             if ( err != noErr) goto errExit;
  610.             
  611.             dataStr[actualSize] = '\0';
  612.             strcat( resultStr, dataStr);
  613.         }
  614.         
  615.         AEDisposeDesc( &morphemeIndexList);
  616.         
  617.         strcat( resultStr, "\n");
  618.         PutCStringConsoleWindow( gConsoleWindow, resultStr);
  619.     }
  620.     
  621.     AEDisposeDesc( &morphemePathList);
  622.     AEDisposeDesc( &morphemeNodeList);
  623.     
  624.     return;
  625.  
  626.     //`````````````````````````````````````````````````````````````````````````````
  627.     // Error handling
  628.     //
  629. errExit:
  630.     if ( morphemeNodeList.descriptorType != typeNull)
  631.         AEDisposeDesc( &morphemeNodeList);
  632.     if ( morphemePathList.descriptorType != typeNull)
  633.         AEDisposeDesc( &morphemePathList);
  634.     if ( morphemeIndexList.descriptorType != typeNull)
  635.         AEDisposeDesc( &morphemeIndexList);
  636.     if ( morphemePath.descriptorType != typeNull)
  637.         AEDisposeDesc( &morphemePath);
  638.     if ( morpheme.descriptorType != typeNull)
  639.         AEDisposeDesc( &morpheme);
  640.     if ( homographList.descriptorType != typeNull)
  641.         AEDisposeDesc( &homographList);
  642.     if ( homograph.descriptorType != typeNull)
  643.         AEDisposeDesc( &homograph);
  644. }
  645.  
  646.  
  647.  /*    ========================================================================================
  648.     Routine:    PrintPath
  649.     
  650.     Purpose:    Print a particular result specified by number in the path.
  651.     
  652.     Warnings:
  653.     ======================================================================================== */
  654. void
  655. PrintPath(
  656.     LAMorphemePath        *thePath,
  657.     short                analysisClass
  658. )
  659. {
  660.     OSStatus            err;
  661.     long                i, j;
  662.     long                morphemeNum, homographNum;
  663.     AEDescList            morphemeNodeList    = { typeNull, NULL};
  664.     AERecord            morpheme            = { typeNull, NULL};
  665.     AEDescList            homographList        = { typeNull, NULL};
  666.     AERecord            homograph            = { typeNull, NULL};
  667.     AEDesc                categoryDesc        = { typeNull, NULL};
  668.     UInt32                categoryCode;
  669.     AEKeyword            theAEKeyword;
  670.     DescType            typeCode;
  671.     long                actualSize;
  672.     char                dataStr[kSizeOfAnalysis];
  673.     char                sourceStr[kSizeOfAnalysis];
  674.     char                categoryName[kMaxCategoryNameLength];
  675.     MorphemeTextRange    textRange;
  676.     HomographWeight        weight;
  677.     HomographAccent        accent;
  678.     char                resultStr[kSizeOfAnalysis];
  679.     char                delimiter;
  680.     
  681.     //------------------------------------------------------------------------------
  682.     // Get source string from path
  683.     //
  684.     err = AEGetKeyPtr( thePath, keyAEText, typeChar, &typeCode, sourceStr,
  685.                        kSizeOfAnalysis, &actualSize);
  686.     if ( err != noErr) goto errExit;
  687.     
  688.     sourceStr[actualSize] = '\0';
  689.     
  690.     //------------------------------------------------------------------------------
  691.     // Get morpheme list from morpheme path
  692.     //
  693.     err = AEGetKeyDesc( thePath, keyAELAMorpheme, typeAEList, &morphemeNodeList);
  694.     if ( err != noErr) goto errExit;
  695.         
  696.     //------------------------------------------------------------------------------
  697.     // Count morphemes
  698.     //
  699.     err = AECountItems( &morphemeNodeList, &morphemeNum);
  700.     if ( err != noErr) goto errExit;
  701.     
  702.     PutCStringConsoleWindow( gConsoleWindow, "\n");
  703.  
  704.     //------------------------------------------------------------------------------
  705.     // Print path info
  706.     //
  707.     sprintf( resultStr, "%3ld morphemes\n", morphemeNum );
  708.     PutCStringConsoleWindow( gConsoleWindow, resultStr);
  709.         
  710.     for ( i = 1; i <= morphemeNum; i++)
  711.     {
  712.         //------------------------------------------------------------------------------
  713.         // Get morpheme node, specified by index, from morpheme node list
  714.         //
  715.         err = AEGetNthDesc( &morphemeNodeList, i, typeAERecord, &theAEKeyword, &morpheme);
  716.         if ( err != noErr) goto errExit;
  717.         
  718.         //------------------------------------------------------------------------------
  719.         // Get text range info from morpheme node
  720.         //
  721.         err = AEGetKeyPtr( &morpheme, keyAEMorphemeTextRange, typeAEMorphemeTextRange,
  722.                            &typeCode, &textRange, sizeof(textRange), &actualSize);
  723.         if ( err != noErr) goto errExit;
  724.         strncpy( dataStr, sourceStr + textRange.sourceOffset, textRange.length);
  725.         dataStr[ textRange.length ] = '\0';
  726.  
  727.         //------------------------------------------------------------------------------
  728.         // Get category name by coercing category code to text
  729.         //
  730.         err = AEGetKeyPtr( &morpheme, keyAEMorphemeCategoryCode, typeAEMorphemeCategoryCode,
  731.                            &typeCode, &categoryCode, sizeof(categoryCode), &actualSize);
  732.         if ( err != noErr) goto errExit;
  733.         
  734.         err = AECoercePtr( typeAEMorphemeCategoryCode, &categoryCode, sizeof(categoryCode),
  735.                            typeChar, &categoryDesc);
  736.         if ( err != noErr) goto errExit;
  737.  
  738.         actualSize = GetHandleSize( categoryDesc.dataHandle);
  739.         BlockMoveData( *categoryDesc.dataHandle, categoryName, actualSize);
  740.         AEDisposeDesc( &categoryDesc);
  741.         categoryName[actualSize] = '\0';
  742.  
  743.         //------------------------------------------------------------------------------
  744.         // Print morpheme info
  745.         //
  746.         sprintf( resultStr, "** %2d: %-16s : %-20s   ", i, dataStr, categoryName);
  747.         PutCStringConsoleWindow( gConsoleWindow, resultStr);
  748.         
  749.         //------------------------------------------------------------------------------
  750.         // Get homograph list from morpheme node
  751.         //
  752.         err = AEGetKeyDesc( &morpheme, keyAELAHomograph, typeAEList, &homographList);
  753.         AEDisposeDesc( &morpheme);
  754.         if ( err != noErr) goto errExit;
  755.         
  756.         err = AECountItems( &homographList, &homographNum);
  757.         
  758.         for ( j = 1; j <= homographNum; j++)
  759.         {
  760.             //------------------------------------------------------------------------------
  761.             // Get homograph node from homograph list
  762.             //
  763.             err = AEGetNthDesc( &homographList, j, typeAERecord, &theAEKeyword, &homograph);
  764.             if ( err != noErr) goto errExit;
  765.             
  766.             //------------------------------------------------------------------------------
  767.             // Get data string (surface string or yomi) from homograph node
  768.             //
  769.             err = AEGetKeyPtr( &homograph, keyAEText, typeChar, &typeCode, dataStr,
  770.                                kSizeOfAnalysis, &actualSize);
  771.             if ( err != noErr) goto errExit;
  772.             dataStr[actualSize] = '\0';
  773.             
  774.             //------------------------------------------------------------------------------
  775.             // Get weight (frequency) from homograph node
  776.             //
  777.             err = AEGetKeyPtr( &homograph, keyAEHomographWeight, typeAEHomographWeight, &typeCode,
  778.                                &weight,  sizeof( weight), &actualSize);
  779.             if ( err != noErr) goto errExit;
  780.             
  781.             //------------------------------------------------------------------------------
  782.             // Get accent from homograph node (TTS mode only)
  783.             //
  784.             if ( analysisClass == kTTSMenuItemID)
  785.             {
  786.                 err = AEGetKeyPtr( &homograph, keyAEHomographAccent, typeAEHomographAccent, &typeCode,
  787.                                    &accent,  sizeof( accent), &actualSize);
  788.                 if ( err != noErr) goto errExit;
  789.             }
  790.             
  791.             delimiter = ( j == homographNum ? ' ' : ',');
  792.             if ( analysisClass == kTTSMenuItemID)
  793.             {
  794.                 sprintf( resultStr, "%s(%d, %d)%c ", dataStr, weight, accent, delimiter);
  795.             }
  796.             else
  797.             {
  798.                 sprintf( resultStr, "%s(%d)%c ", dataStr, weight, delimiter);
  799.             }
  800.             PutCStringConsoleWindow( gConsoleWindow, resultStr);
  801.             
  802.             AEDisposeDesc( &homograph);
  803.         }
  804.         PutCStringConsoleWindow( gConsoleWindow, "\n");
  805.         
  806.         AEDisposeDesc( &homographList);
  807.     }
  808.     PutCStringConsoleWindow( gConsoleWindow, "\n");
  809.         
  810.     AEDisposeDesc( &morphemeNodeList);
  811.     
  812.     return;
  813.  
  814.     //`````````````````````````````````````````````````````````````````````````````
  815.     // Error handling
  816.     //
  817. errExit:
  818.     if ( morphemeNodeList.descriptorType != typeNull)
  819.         AEDisposeDesc( &morphemeNodeList);
  820.     if ( morpheme.descriptorType != typeNull)
  821.         AEDisposeDesc( &morpheme);
  822.     if ( homographList.descriptorType != typeNull)
  823.         AEDisposeDesc( &homographList);
  824.     if ( homograph.descriptorType != typeNull)
  825.         AEDisposeDesc( &homograph);
  826. }
  827.  
  828.  
  829.  /*    ========================================================================================
  830.     Routine:    PrintStreamFromPath
  831.     
  832.     Purpose:    Print a result in the standalone path.
  833.     
  834.     Warnings:
  835.     ======================================================================================== */
  836. void
  837. PrintStreamFromPath(
  838.     LAMorphemePath        *thePath
  839. )
  840. {
  841.     OSStatus        err;
  842.     long            i, morphemeNum;
  843.     AEDescList        morphemeNodeList    = { typeNull, NULL};
  844.     AERecord        morpheme            = { typeNull, NULL};
  845.     AEDescList        homographList        = { typeNull, NULL};
  846.     AERecord        homograph            = { typeNull, NULL};
  847.     AEKeyword        theAEKeyword;
  848.     DescType        typeCode;
  849.     long            actualSize;
  850.     char            dataStr[kSizeOfAnalysis];
  851.     char            resultStr[kSizeOfAnalysis];
  852.     
  853.     //------------------------------------------------------------------------------
  854.     // Get morpheme list from morpheme path
  855.     //
  856.     err = AEGetKeyDesc( thePath, keyAELAMorpheme, typeAEList, &morphemeNodeList);
  857.     if ( err != noErr) goto errExit;
  858.     
  859.     //------------------------------------------------------------------------------
  860.     // Count morphemes
  861.     //
  862.     err = AECountItems( &morphemeNodeList, &morphemeNum);
  863.     if ( err != noErr) goto errExit;
  864.     
  865.     for ( resultStr[0] = 0, i = 1; i <= morphemeNum; i++)
  866.     {
  867.         //------------------------------------------------------------------------------
  868.         // Get morpheme node, specified by index, from morpheme node list
  869.         //
  870.         err = AEGetNthDesc( &morphemeNodeList, i, typeAERecord, &theAEKeyword, &morpheme);
  871.         if ( err != noErr) goto errExit;
  872.         
  873.         //------------------------------------------------------------------------------
  874.         // Get homograph list from morpheme node
  875.         //
  876.         err = AEGetKeyDesc( &morpheme, keyAELAHomograph, typeAEList, &homographList);
  877.         AEDisposeDesc( &morpheme);
  878.         if ( err != noErr) goto errExit;
  879.         
  880.         //------------------------------------------------------------------------------
  881.         // Get homograph node from homograph list
  882.         //
  883.         err = AEGetNthDesc( &homographList, 1, typeAERecord, &theAEKeyword, &homograph);
  884.         AEDisposeDesc( &homographList);
  885.         if ( err != noErr) goto errExit;
  886.         
  887.         //------------------------------------------------------------------------------
  888.         // Get data string (surface string or yomi) from homograph node
  889.         //
  890.         err = AEGetKeyPtr( &homograph, keyAEText, typeChar, &typeCode, dataStr,
  891.                            kSizeOfAnalysis, &actualSize);
  892.         AEDisposeDesc( &homograph);
  893.         if ( err != noErr) goto errExit;
  894.         
  895.         dataStr[actualSize] = '\0';
  896.         strcat( resultStr, dataStr);
  897.     }
  898.     
  899.     strcat( resultStr, "\n");
  900.     PutCStringConsoleWindow( gConsoleWindow, resultStr);
  901.     
  902.     AEDisposeDesc( &morphemeNodeList);
  903.     
  904.     return;
  905.     
  906.     //`````````````````````````````````````````````````````````````````````````````
  907.     // Error handling
  908.     //
  909. errExit:
  910.     if ( homographList.descriptorType != typeNull)
  911.         AEDisposeDesc( &homographList);
  912.     if ( homograph.descriptorType != typeNull)
  913.         AEDisposeDesc( &homograph);
  914.     if ( morpheme.descriptorType != typeNull)
  915.         AEDisposeDesc( &morpheme);
  916.     if ( morphemeNodeList.descriptorType != typeNull)
  917.         AEDisposeDesc( &morphemeNodeList);
  918. }
  919.  
  920.  
  921.  /*    ========================================================================================
  922.     Routine:    GetStandalonePathFromBundle
  923.     
  924.     Purpose:    Get the specified path from bundle structure.
  925.     
  926.     Warnings:
  927.     ======================================================================================== */
  928. static OSStatus
  929. GetStandalonePathFromBundle(
  930.     LAMorphemeBundle    *bundle,
  931.     UInt16                index,
  932.     LAMorphemePath        *morphemePath
  933. )
  934. {
  935.     OSStatus            err;
  936.     AEKeyword            theAEKeyword;
  937.     AEDescList            morphemeNodeList;
  938.     AEDescList            bundleNodeList, bundlePathList,  bundleIndexList;
  939.     AEDesc                tempDesc, morpheme;
  940.     DescType            typeCode;
  941.     long                actualSize, morphemeNum, morphemeIndex, i;
  942.     AERecord            bundlePath;
  943.  
  944.     //------------------------------------------------------------------------------
  945.     // Create morpheme path
  946.     //
  947.     err = AECreateList( NULL, 0L, true, morphemePath);
  948.     nrequire( err, createMorphemePath_Failure);
  949.  
  950.     //------------------------------------------------------------------------------
  951.     // Copy bundle's source text to morpheme path
  952.     //
  953.     err = AEGetKeyDesc( bundle, keyAEText, typeChar, &tempDesc);
  954.     nrequire( err, getSourceStr_Failure);
  955.     
  956.     err = AEPutKeyDesc( morphemePath, keyAEText, &tempDesc);
  957.     AEDisposeDesc( &tempDesc);
  958.     nrequire( err, setSourceStr_Failure);
  959.     
  960.     //------------------------------------------------------------------------------
  961.     // Create new morpheme node list
  962.     //
  963.     err = AECreateList( NULL, 0L, false, &morphemeNodeList);
  964.     nrequire( err, createMorphemeNodeList_Failure);
  965.     
  966.     //------------------------------------------------------------------------------
  967.     // Get bundle's morpheme node list
  968.     //
  969.     err = AEGetKeyDesc( bundle, keyAELAMorpheme, typeAEList, &bundleNodeList);
  970.     nrequire( err, getBundleNodeList_Failure);
  971.  
  972.     //------------------------------------------------------------------------------
  973.     // Get bundle's morpheme path list
  974.     //
  975.     err = AEGetKeyDesc( bundle, keyAELAMorphemePath, typeAEList, &bundlePathList);
  976.     nrequire( err, getBundlePathList_Failure);
  977.     
  978.     //------------------------------------------------------------------------------
  979.     // Get specified bundle's path
  980.     //
  981.     err = AEGetNthDesc( &bundlePathList, index, typeAERecord, &theAEKeyword, &bundlePath);
  982.     AEDisposeDesc( &bundlePathList);
  983.     nrequire( err, getBundlePath_Failure);
  984.     
  985.     //------------------------------------------------------------------------------
  986.     // Get path's morpheme list
  987.     //
  988.     err = AEGetKeyDesc( &bundlePath, keyAELAMorpheme, typeAEList, &bundleIndexList);
  989.     AEDisposeDesc( &bundlePath);
  990.     nrequire( err, getBundleIndexList_Failure);
  991.     
  992.     //------------------------------------------------------------------------------
  993.     // Get bundle's morpheme list from path
  994.     //
  995.     err = AECountItems( &bundleIndexList, &morphemeNum);
  996.     nrequire( err, getMorphemeCount_Failure);
  997.     
  998.     //------------------------------------------------------------------------------
  999.     // Copy all morpheme node
  1000.     //
  1001.     for ( i = 1; i <= morphemeNum; i++)
  1002.     {
  1003.         //------------------------------------------------------------------------------
  1004.         // Get morpheme index from morpheme index list one by one
  1005.         //
  1006.         err = AEGetNthPtr( &bundleIndexList, i, typeInteger, &theAEKeyword, &typeCode,
  1007.                            &morphemeIndex, sizeof(morphemeIndex), &actualSize);
  1008.         nrequire( err, getMorphemeIndex_Failure);
  1009.         
  1010.         //------------------------------------------------------------------------------
  1011.         // Get morpheme node, specified by index, from morpheme node list
  1012.         //
  1013.         err = AEGetNthDesc( &bundleNodeList, morphemeIndex, typeAERecord, &theAEKeyword,
  1014.                             &morpheme);
  1015.         nrequire( err, getMorphemeNode_Failure);
  1016.         
  1017.         //------------------------------------------------------------------------------
  1018.         // Copy morpheme node
  1019.         //
  1020.         err = AEPutDesc( &morphemeNodeList, 0, &morpheme);
  1021.         AEDisposeDesc( &morpheme);
  1022.         nrequire( err, putMorphemeNode_Failure);
  1023.     }
  1024.     
  1025.     //------------------------------------------------------------------------------
  1026.     // Add morpheme node list to morpheme path
  1027.     //
  1028.     err = AEPutKeyDesc( morphemePath, keyAELAMorpheme, &morphemeNodeList);
  1029.     nrequire( err, addMorphemeListToPath_Failure);
  1030.     
  1031.     AEDisposeDesc( &bundleIndexList);
  1032.     AEDisposeDesc( &bundleNodeList);
  1033.     AEDisposeDesc( &morphemeNodeList);
  1034.  
  1035.     return noErr;
  1036.     
  1037.     //`````````````````````````````````````````````````````````````````````````````
  1038.     // Error handling
  1039.     //
  1040. addMorphemeListToPath_Failure:
  1041. putMorphemeNode_Failure:
  1042. getMorphemeNode_Failure:
  1043. getMorphemeIndex_Failure:
  1044. getMorphemeCount_Failure:
  1045.     AEDisposeDesc( &bundleIndexList);
  1046. getBundleIndexList_Failure:
  1047. getBundlePath_Failure:
  1048. getBundlePathList_Failure:
  1049.     AEDisposeDesc( &bundleNodeList);
  1050. getBundleNodeList_Failure:
  1051.     AEDisposeDesc( &morphemeNodeList);
  1052. createMorphemeNodeList_Failure:
  1053. setSourceStr_Failure:
  1054. getSourceStr_Failure:
  1055. createMorphemePath_Failure:
  1056.     return err;
  1057. }
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.  
  1064.